#include <graphics/GLBufferObjectManager.h>

namespace ne
{
    template<> GLBufferObjectManager* Singleton<GLBufferObjectManager>::mpInstance = 0;

    GLBufferObjectManager::GLBufferObjectManager()
    {
        std::cout << "Construct GLBufferObject Manager\n";
    }

    GLBufferObjectPtr GLBufferObjectManager::createBufferObject(const BufferType bt, const BufferUsage usage, const uint32_t length)
    {
        GLBufferObjectPtr pBuffer(new GLBufferObject(bt, usage, length));
        mGLBufferObjectMap[pBuffer->getSource()] = pBuffer;
        return pBuffer;
    }

    GLBufferObjectPtr GLBufferObjectManager::getBufferObject(const uint32_t source) const
    {
        GLBufferObjectMapConstIterator it = mGLBufferObjectMap.find(source);
        if (it != mGLBufferObjectMap.end())
        {
            return it->second;
        }
        return GLBufferObjectPtr();
    }

    bool GLBufferObjectManager::hasBufferObject(const uint32_t source) const
    {
        GLBufferObjectMapConstIterator it = mGLBufferObjectMap.find(source);
        if (it != mGLBufferObjectMap.end())
        {
            return true;
        }
        return false;
    }

    bool GLBufferObjectManager::removeByPtr(GLBufferObjectPtr pBuffer)
    {
        if (pBuffer.notNull())
        {
            return removeBySource(pBuffer->getSource());
        }
        return false;
    }

    bool GLBufferObjectManager::removeBySource(const uint32_t source)
    {
        GLBufferObjectMapIterator it = mGLBufferObjectMap.find(source);
        if (it != mGLBufferObjectMap.end())
        {
            mGLBufferObjectMap.erase(it);
            return true;
        }
        return false;
    }

    void GLBufferObjectManager::removeAll()
    {
        mGLBufferObjectMap.clear();
    }

    GLBufferObjectManager::~GLBufferObjectManager()
    {
        removeAll();
        std::cout << "Disconstruct GLBufferObject Manager\n";
    }

    GLBufferObjectManager& GLBufferObjectManager::GetSingleton()
    {
        assert(mpInstance);
        return *mpInstance;
    }

    GLBufferObjectManager* GLBufferObjectManager::GetSingletonPtr()
    {
        return mpInstance;
    }
}
